import { warn } from '@/utils/log'
// eslint-disable-next-line
import { BasicLayout, BlankLayout, PageView, RouteView } from '@/layouts'
import { AppRouteModule, AppRouteRecordRaw } from '/#/types'
import { Exception404, IFRAME, RootRouter } from '../constant'

const LayoutMap = new Map<string, any>()
export type LayoutMapKey = 'RouteView'

LayoutMap.set('RouteView', RouteView as any)
LayoutMap.set('BasicLayout', BasicLayout as any)
LayoutMap.set('BlankLayout', BlankLayout as any)
LayoutMap.set('PageView', PageView as any)
LayoutMap.set('404', Exception404 as any)
LayoutMap.set('Exception404', Exception404 as any)
LayoutMap.set('IFRAME', IFRAME as any)

let dynamicViewsModules: Record<string, () => Promise<Recordable>>

// Turn background objects into routing objects
// 将背景对象变成路由对象
export function transformObjToRoute<T = AppRouteModule>(routeList: AppRouteModule[]): T[] {
  dynamicViewsModules = dynamicViewsModules || import.meta.glob('../../views/**/*.{vue,tsx}')
  RootRouter.children = routeList
  const AllRouter = [RootRouter]
  AllRouter.forEach((route) => {
    const component = route.component as string
    if (component) {
      const { hidden, hideChildren } = route.meta || {}
      // route.children = [cloneDeep(route)]
      route.component = dynamicImport(dynamicViewsModules, route.component || route.key)
      //   route.name = `${route.name}Parent`;
      route.name = route.name || route.key || ''
      route.path = route.path
      const meta = route.meta || {}
      route.hidden = meta.hidden
      route.hideChildrenInMenu = meta.hideChildren
      // 是否设置了隐藏菜单
      route.hidden = hidden
      // 是否设置了隐藏子菜单
      route.hideChildrenInMenu = hideChildren
    } else {
      warn('请正确配置路由：' + route?.name + '的component属性')
    }
    route.children && asyncImportRoute(route.children)
  })
  return AllRouter as unknown as T[]
}

// Dynamic introduction
function asyncImportRoute(routes: AppRouteRecordRaw[] | undefined) {
  if (!routes) return
  routes.forEach((item) => {
    if (!item.component && item.meta?.frameSrc) {
      item.component = 'IFRAME'
    }
    const { component } = item
    const { children } = item
    if (component) {
      const { hidden, hideChildren } = item.meta || {}
      const layoutFound = LayoutMap.get(component as string)
      item.name = item.name || item.key || ''
      item.path = item.path
      // 是否设置了隐藏菜单
      item.hidden = hidden
      // 是否设置了隐藏子菜单
      item.hideChildrenInMenu = hideChildren
      if (layoutFound) {
        item.component = layoutFound
      } else {
        item.component = dynamicImport(dynamicViewsModules, component as string)
      }
    }
    children && asyncImportRoute(children)
  })
}

/**
 * vite 动态引入组件
 * @param {*} dynamicViewsModules
 * @param {*} component
 * @returns
 */
function dynamicImport(dynamicViewsModules, component) {
  const layoutFound = LayoutMap.get(component as string)
  if (layoutFound) return layoutFound
  const keys = Object.keys(dynamicViewsModules)
  const matchKeys = keys.filter((key) => {
    // 加一个异常捕获
    try {
      const k = key.replace('../../views', '')
      const startFlag = component.startsWith('/')
      const endFlag = component.endsWith('.vue') || component.endsWith('.tsx')
      const startIndex = startFlag ? 0 : 1
      const lastIndex = endFlag ? k.length : k.lastIndexOf('.')
      return k.substring(startIndex, lastIndex) === component
    } catch (error) {
      console.log('dynamicImport-error', error)
    }
  })
  if (matchKeys?.length === 1) {
    const matchKey = matchKeys[0]
    return dynamicViewsModules[matchKey]
  } else if (matchKeys?.length > 1) {
    warn(
      'Please do not create `.vue` and `.TSX` files with the same file name in the same hierarchical directory under the views folder. This will cause dynamic introduction failure'
    )
    return
  } else {
    warn('在src/views/下找不到`' + component + '.vue` 或 `' + component + '.tsx`, 请自行创建!')
    return Exception404
  }
}
